﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NPipeline.Stage
{
    public class PoolObjectsStage<T> : BaseStage
    {
        public int PoolSize { get; set; }
        public List<T> PooledObjects { get; set; }

        public PoolObjectsStage()
        {
            _Init(1);
        }

        public PoolObjectsStage(int poolSize)
        {
            _Init(poolSize);
            
        }

        private void _Init(int poolSize)
        {
            PoolSize = poolSize;
            PooledObjects = new List<T>(PoolSize);

        }

        public override void Process(object obj)
        {

            if (obj is T)
            {
                List<T> poolToEmit = null;

                lock (this)
                {
                    PooledObjects.Add((T)obj);

                    // check if we reached the PoolSize
                    if (PooledObjects.Count >= PoolSize)
                    {
                        // Emit to next stage and create new Pool
                        poolToEmit = PooledObjects;
                        PooledObjects = new List<T>(PoolSize);
                    }
                }

                if (poolToEmit != null)
                {
                    Emit(poolToEmit);
                }

            }
            else // this is questionable - only pool objects we know ??
            {
                Emit(obj);
            }
        }

        public override void PostProcess()
        {
            base.PostProcess();
            // make sure we emit the rest
            // should we lock it ?
            if (PooledObjects.Count > 0)
            {
                Emit(PooledObjects);
            }
        }


    }
}
